package com.example.demo.utils.wx;

import com.alibaba.fastjson.JSON;
import com.example.demo.utils.common.StringUtils;
import com.example.demo.utils.encryption.AESUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class WxPayNotifyService {

    /**
     * 支付回调
     * 此函数会被执行多次，如果支付状态已经修改为已支付，则下次再调的时候判断是否已经支付，如果已经支付了，则不执行
     */
    public void notifyWXPay(HttpServletRequest request, HttpServletResponse response) {

        try {
            System.out.println("微信支付回调");
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            String resultxml = new String(outSteam.toByteArray(), "utf-8");
            Map<String, String> params = WxUtil.doXMLParse(resultxml);
            outSteam.close();
            inStream.close();


            Map<String, String> return_data = new HashMap<String, String>();
            if (!WxUtil.isTenpaySign(params, WxConfig.merkey)) {
                // 支付失败
                return_data.put("return_code", "FAIL");
                return_data.put("return_msg", "return_code不正确");
            } else {
                System.out.println("===============付款成功==============");
                // ------------------------------
                // 处理业务开始
                // ------------------------------
                // 此处处理订单状态，结合自己的订单数据完成订单状态的更新
                // ------------------------------
                String return_code = params.get("return_code");
                if (StringUtils.equals("SUCCESS", return_code)) {
                    /** zhangxy:支付成功后，处理相关业务 */
                    params.get("total_fee");
                    params.get("transaction_id");
                    params.get("out_trade_no");
                    params.get("time_end");

                    /** 通知微信回调成功 */
                    String resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    BufferedOutputStream out = new BufferedOutputStream(
                            response.getOutputStream());
                    out.write(resXml.getBytes());
                    out.flush();
                    out.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加密串-req_info
     * 退款回调第一步 对加密串A做base64解码，得到加密串B
     * 退款回调第二步 对商户key做md5，得到32位小写key* ( key设置路径：微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 )
     * 退款第三步-用key*对加密串B做AES-256-ECB解密（PKCS7Padding）
     */
    public void notifyWXRefund(HttpServletRequest request, HttpServletResponse response) {

        try {
            System.out.println("微信退款回调");
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            String resultxml = new String(outSteam.toByteArray(), "utf-8");
            Map<String, String> params = WxUtil.doXMLParse(resultxml);
            outSteam.close();
            inStream.close();
            System.out.println(JSON.toJSONString(params));

            try {

                if (StringUtils.equals("SUCCESS", params.get("return_code"))) {

                    /**
                     * 退款回调解密
                     *  {
                     *                 "transaction_id":"4200000455201911194989928580",
                     *                     "refund_status":"SUCCESS",
                     *                     "out_refund_no":"BHCCRVPfetTINc7UoWRxswCMWs5PrSd9",
                     *                     "settlement_refund_fee":"1",
                     *                     "success_time":"2019-11-19 10:07:04",
                     *                     "refund_recv_accout":"支付用户零钱",
                     *                     "refund_id":"50000402502019111913301742973",
                     *                     "out_trade_no":"U4cshBSNw8Fuazkq1CwfklMXIv9XpuUH",
                     *                     "refund_account":"REFUND_SOURCE_RECHARGE_FUNDS",
                     *                     "refund_fee":"1",
                     *                     "total_fee":"1",
                     *                     "settlement_total_fee":"1",
                     *                     "refund_request_source":"API"
                     *             }
                     * */
                    String req_info = params.get("req_info");
                    String decryptData = AESUtil.decryptData(req_info, WxConfig.merkey);
                    Map<String, String> reqParams = WxUtil.doXMLParse(decryptData);
                    System.out.println(JSON.toJSONString(reqParams));

                    reqParams.get("out_refund_no");
                    reqParams.get("refund_status");
                    reqParams.get("success_time");

                    /** 根据返回的退款状态，处理相关业务 */

                } else {
                    System.out.println("退款失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
